package com.hhf.rpc.core.handler;

import com.hhf.rpc.core.enums.ProtocolMessageTypeEnum;
import com.hhf.rpc.core.model.RpcRequest;
import com.hhf.rpc.core.model.RpcResponse;
import com.hhf.rpc.core.protocol.ProtocolMessage;
import com.hhf.rpc.core.protocol.ProtocolMessageDecoder;
import com.hhf.rpc.core.protocol.ProtocolMessageEncoder;
import com.hhf.rpc.core.registry.LocalRegistry;
import io.vertx.core.Handler;
import io.vertx.core.buffer.Buffer;
import io.vertx.core.net.NetSocket;

import java.io.IOException;
import java.lang.reflect.Method;

/**
 * @Author hhf
 * @Date 2024/10/19
 * @Description
 */
public class TcpServerHandler implements Handler<NetSocket> {
    @Override
    public void handle(NetSocket netSocket) {
        //处理连接
        netSocket.handler(buffer -> {
            //接受请求,解码
            ProtocolMessage<RpcRequest> protocolMessage;
            try {
                protocolMessage = (ProtocolMessage<RpcRequest>) ProtocolMessageDecoder.decode(buffer);
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
            RpcRequest rpcRequest = protocolMessage.getBody();
            //处理请求
            RpcResponse rpcResponse = new RpcResponse();
            //4.根据请求的serviceName和methodName找对应的实现类,进行调用(反射原理)
            try {
                Class<?> implClass = LocalRegistry.get(rpcRequest.getServiceName());
                Method method = implClass.getMethod(rpcRequest.getMethodName(), rpcRequest.getParameterTypes());
                Object invoke = method.invoke(implClass.getDeclaredConstructor().newInstance(), rpcRequest.getArgs());
                //封装结果
                rpcResponse.setMessage("ok");
                rpcResponse.setData(invoke);
                rpcResponse.setDataType(method.getReturnType());
            } catch (Exception e) {
                e.printStackTrace();
                rpcResponse.setException(e);
                rpcResponse.setMessage(e.getMessage());
            }
            //发送响应,编码
            ProtocolMessage.Header header = protocolMessage.getHeader();
            header.setType((byte) ProtocolMessageTypeEnum.RESPONSE.getKey());
            ProtocolMessage<RpcResponse> rpcResponseProtocolMessage = new ProtocolMessage<>(rpcResponse, header);
            try {
                Buffer resultBuffer = ProtocolMessageEncoder.encode(rpcResponseProtocolMessage);
                netSocket.write(resultBuffer);
            } catch (IOException e) {
                throw new RuntimeException("协议消息编码失败:" + e);
            }
        });
    }
}
